package com.advertisementsystem.Servie.Impl;

import com.advertisementsystem.Exception.BusinessException;
import com.advertisementsystem.Dto.LoginUser;
import com.advertisementsystem.Mapper.DeviceIncomeMapper;
import com.advertisementsystem.Mapper.DeviceMapper;
import com.advertisementsystem.Mapper.StatisticsMapper;
import com.advertisementsystem.Servie.DeviceStatisticsService;
import com.advertisementsystem.entity.Device;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class DeviceStatisticsServiceImpl implements DeviceStatisticsService {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private StatisticsMapper statisticsMapper;

    @Autowired
    private DeviceIncomeMapper deviceIncomeMapper;

    @Override
    public Map<String, Object> getDeviceStatistics(Long deviceId) {
        // 检查设备是否存在
        Device device = deviceMapper.selectById(deviceId);
        if (device == null) {
            throw new BusinessException("设备不存在");
        }

        // 检查权限
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        if (!loginUser.getPermissions().contains("ROLE_ADMIN") &&
                !device.getOwnerId().equals(loginUser.getUser().getId())) {
            throw new BusinessException("无权查看此设备统计");
        }

        // 获取统计数据
        Map<String, Object> statistics = new HashMap<>();

        // 总播放次数
        Integer totalPlayCount = statisticsMapper.getDeviceTotalPlayCount(deviceId);
        statistics.put("totalPlayCount", totalPlayCount);

        // 总观看次数
        Integer totalViewCount = statisticsMapper.getDeviceTotalViewCount(deviceId);
        statistics.put("totalViewCount", totalViewCount);

        // 日期维度统计
        List<Map<String, Object>> dailyStats = statisticsMapper.getDeviceDailyStatistics(deviceId);
        statistics.put("dailyStats", dailyStats);

        // 广告维度统计
        List<Map<String, Object>> adStats = statisticsMapper.getDeviceAdStatistics(deviceId);
        statistics.put("adStats", adStats);

        // 最近7天统计
        List<Map<String, Object>> weeklyStats = statisticsMapper.getDeviceWeeklyStatistics(deviceId);
        statistics.put("weeklyStats", ensureCompleteWeekData(weeklyStats));

        return statistics;
    }

    @Override
    public Map<String, Object> getDeviceIncomeStats(Long deviceId) {
        // 检查设备是否存在
        Device device = deviceMapper.selectById(deviceId);
        if (device == null) {
            throw new BusinessException("设备不存在");
        }

        // 获取收入统计数据
        Map<String, Object> incomeStats = new HashMap<>();

        // 总收入
        BigDecimal totalIncome = deviceIncomeMapper.getDeviceTotalIncome(deviceId);
        incomeStats.put("total", totalIncome);

        // 月收入
        BigDecimal monthlyIncome = deviceIncomeMapper.getDeviceMonthlyIncome(deviceId);
        incomeStats.put("monthly", monthlyIncome);

        return incomeStats;
    }

    @Override
    public List<Map<String, Object>> getDeviceWeeklyIncome(Long deviceId) {
        // 获取最近7天的收入数据
        List<Map<String, Object>> weeklyIncome = deviceIncomeMapper.getDeviceWeeklyIncome(deviceId);

        // 确保返回完整的7天数据
        return ensureCompleteWeekData(weeklyIncome);
    }

    @Override
    public Map<String, Object> getDeviceAdSchedules(Long deviceId, int pageNum, int pageSize) {
        // 分页参数
        int offset = (pageNum - 1) * pageSize;

        // 获取广告排期
        List<Map<String, Object>> schedules = deviceIncomeMapper.getDeviceAdSchedules(deviceId, pageSize, offset);

        // 获取总数
        int total = deviceIncomeMapper.countDeviceAdSchedules(deviceId);

        Map<String, Object> result = new HashMap<>();
        result.put("records", schedules);
        result.put("total", total);
        result.put("size", pageSize);
        result.put("current", pageNum);

        return result;
    }

    /**
     * 确保返回完整的7天数据，如果某天没有数据则补充为0
     */
    private List<Map<String, Object>> ensureCompleteWeekData(List<Map<String, Object>> data) {
        Map<String, Object> dataMap = new HashMap<>();
        for (Map<String, Object> item : data) {
            // 修复：将 java.sql.Date 转换为字符串
            Object dateObj = item.get("date");
            String dateStr;
            if (dateObj instanceof java.sql.Date) {
                // 如果是 java.sql.Date 类型，转换为 String
                java.sql.Date sqlDate = (java.sql.Date) dateObj;
                dateStr = sqlDate.toString(); // 格式为 "yyyy-MM-dd"
            } else if (dateObj instanceof String) {
                // 如果已经是字符串，直接使用
                dateStr = (String) dateObj;
            } else {
                // 其他情况，转换为字符串
                dateStr = dateObj != null ? dateObj.toString() : "";
            }

            // 使用转换后的字符串作为键
            dataMap.put(dateStr, item);
        }

        List<Map<String, Object>> result = new ArrayList<>();
        Calendar calendar = Calendar.getInstance();

        for (int i = 6; i >= 0; i--) {
            Calendar cal = (Calendar) calendar.clone();
            cal.add(Calendar.DAY_OF_MONTH, -i);

            String dateStr = String.format("%d-%02d-%02d",
                    cal.get(Calendar.YEAR),
                    cal.get(Calendar.MONTH) + 1,
                    cal.get(Calendar.DAY_OF_MONTH));

            if (dataMap.containsKey(dateStr)) {
                result.add((Map<String, Object>) dataMap.get(dateStr));
            } else {
                Map<String, Object> emptyDay = new HashMap<>();
                emptyDay.put("date", dateStr);
                emptyDay.put("amount", BigDecimal.ZERO);
                // 如果是统计数据，可能还需要添加其他字段
                if (!data.isEmpty() && data.get(0).containsKey("play_count")) {
                    emptyDay.put("play_count", 0);
                    emptyDay.put("view_count", 0);
                }
                result.add(emptyDay);
            }
        }

        return result;
    }
}